import path from 'path' 
import fs from 'fs'

import PROJECT from './PROJECT'

class FilesMapPlugin {
  constructor({
    filename = ''
  } = {}) {
    this.opt = { filename }
  }

  filesMap(compilation, callback) {
    const input = compilation.getStats().toJson({
      publicPath: true,
      outputPath: true,
      chunks: true
    })
    // console.log(input)
    const output = this.parse(input)
    this.write(output, input).then(callback)
  }

  parse(input) {
    const output = {}
    input.chunks.map(chunk => {
      chunk.modules.map(mod => {
        if (mod.id === '') { return }
        if (mod.assets.length !== 0) {
          // console.log(absoluteUrl, mod.name)
          const absoluteUrl = path.resolve(__dirname, mod.name)
          const relativeUrl = path.relative(PROJECT.SRC.ROOT, absoluteUrl)
          output[relativeUrl] = input.publicPath + mod.assets[0]
        }
      })
    })
    return output
  }

  write(output, input) {
    return new Promise((ok, fail) => fs.writeFile(
      path.resolve(input.outputPath, this.opt.filename),
      JSON.stringify(output, null, 2),
      err => err ? fail(err) : ok()
    ))
  }

  apply(compiler) {
    // emit is asynchronous hook, tapping into it using tapAsync, you can use tapPromise/tap(synchronous) as well
    compiler.hooks.afterEmit.tapAsync('FilesMapPlugin', this.filesMap.bind(this));
  }
}

export { FilesMapPlugin }
